import Square from "@/components/Square/Square"
import { use, useState } from "react"
import "@/assets/Board.css"

// 用于创建x：y的棋盘
/**
 * 
 * @param x 横向棋盘大小
 * @param y 纵向棋盘大小
 * @returns X x Y的棋盘
 */
function creatSquare(x:number,y:number){
    const result = []
    for(let i=0;i<y;i++){
        const floor = []
        for(let j=0;j<x;j++){
            floor.push(i*3+j+1)
        }
        result.push(floor)
    }
    return result
}

// 胜利条件
/**
 * 
 * @param board  棋盘
 * @param row    棋子x点位
 * @param col    棋子y点位
 * @param player 当前玩家棋子类型
 * @param winCount 胜利所需连续棋子数
 * @returns 
 */
function checkWin(board:Array<Array<string>>, row:number, col:number, player:string,winCount:number=3) {
  const directions = [
    [0, 1],  // 横向 →
    [1, 0],  // 纵向 ↓
    [1, 1],  // 斜向 ↘
    [1, -1]  // 斜向 ↙
  ];
  const theWin = winCount + 1
  for (const [dx, dy] of directions) {
    let count = 1;  // 当前落子点已有一子
    // 正向检查
    for (let i = 1; i <= theWin; i++) {
      const newRow = row + dx * i;
      const newCol = col + dy * i;
      if (board[newRow]?.[newCol] !== player) break;
      count++;
    }
    // 反向检查
    for (let i = 1; i <= theWin; i++) {
      const newRow = row - dx * i;
      const newCol = col - dy * i;
      if (board[newRow]?.[newCol] !== player) break;
      count++;
    }
    if (count >= winCount) return true; // 五连达成
  }
  return false;
}

interface OperateItem {
    title: string;
    id: Number; // 最好有唯一id而不是用index作为key
}

// 操作列表
const operateList:Array<OperateItem> = [
    {
        id:1,
        title:"重新开始",
    },
    {
        id:2,
        title:'悔棋',
    },
    {
        id:3,
        title:'取消悔棋'
    }
]

export default function Board() {
    // 棋盘
    const [board,setBoard] = useState<any>(creatSquare(3,3))
    // 棋子
    const [squares,setSquares] = useState(Array(3).fill(null).map(() => Array(3).fill(null))) 
    // 记录当前
    const [play,setPlay] = useState("X")
    // 当前的棋子点位
    const [current_step,setCurrent_step] = useState([null,null])
    // 是否获胜
    const [win,setWin] = useState("")
    // 记录历史
    const [history,setHistory] = useState([{
        squares,
        current_step,
        win,
        play
    }])
    const squareCheck = (x:number,y:number)=>{
        // 重置悔棋次数
        setRetractCount(0)
        // 判断是否有人获胜
        if(win){
            return
        }
        // 判断该点位是否已经有棋子
        if(squares[x][y]){
            return
        }
        // ✅ 创建真正的二维数组拷贝
        const newSquares = squares.map(row => [...row]);
        // ✅ 安全修改指定位置
        newSquares[x][y] = play;
        // 更新步数记录
        setPlay(play==="X"?"O":"X")
        // 更新当前最新的棋子位置
        setCurrent_step([x,y])
        // 更新棋子
        setSquares(newSquares)
        // 检查胜方
        const isWin = checkWin(newSquares,x,y,newSquares[x][y])
        if(isWin){
            setWin(play)
        }
        // 记录历史
        setHistory([...history,
            {   
                squares:newSquares,
                current_step:[x,y],
                win:isWin?play:"",
                play
            }
        ])
    }
    // 重新开始
    const rePlay = ()=>{
        // 清空棋子
        setSquares(Array(3).fill(null).map(() => Array(3).fill(null)))
        // 置空当前步骤
        setCurrent_step([null,null])
        // 重置胜利
        setWin("")
        // 重置棋子种类
        setPlay("X")
        // 重置悔棋次数
        setRetractCount(0)
        // 清空历史
        setHistory([{
            squares:Array(3).fill(null).map(() => Array(3).fill(null)),
            current_step:[null,null],
            win:"",
            play:"X"
        }])
    }
    // 悔棋 
    // 悔棋次数
    const [retractCount,setRetractCount] = useState(0)
    const retract = ()=>{
        if(history.length-1-1-retractCount >= 0){
            setRetractCount(retractCount+1);
            setSquares(history[history.length-1-1-retractCount].squares)
            // 重新判断棋子种类
            setPlay(history[history.length-1-1-retractCount].play === "X"?"O":"X")
            // 获取当前棋子位置
            setCurrent_step(history[history.length-1-1-retractCount].current_step)
            // 重置胜利
            setWin(history[history.length-1-1-retractCount].win)
        }
    }
    // 取消悔棋
    const removeRetract = ()=>{
        if(retractCount > 0){
            setRetractCount(retractCount-1);
            setSquares(history[history.length-retractCount].squares)
            // 重新判断棋子种类
            setPlay(history[history.length-retractCount].play === "X"?"O":"X")
            // 获取当前棋子位置
            setCurrent_step(history[history.length-retractCount].current_step)
            // 重置胜利
            setWin(history[history.length-retractCount].win)
        }
    }
    return <>
        <div>
            <div className="w-36 mx-auto">
                {board.map((row:any,rowIndex:number)=>{
                    return <div className="h-12 flex " key={rowIndex}>
                        {row.map((col:any,colIndex:number) => {
                            if(rowIndex === current_step[0] && colIndex === current_step[1]){
                                return <Square key={col} current={true} value={squares[rowIndex][colIndex]} onSquareClick={()=>squareCheck(rowIndex,colIndex)}/>
                            }else{
                                return <Square key={col} value={squares[rowIndex][colIndex]} onSquareClick={()=>squareCheck(rowIndex,colIndex)}/>
                            }
                        })}
                    </div>
                })}
            </div>
        </div>
        <div className="flex justify-center text-center mt-4 items-center">
            <ul>
                {win && <li>{win}获胜了</li>}
                {
                operateList.map((operate:OperateItem)=>{
                    if(operate.id === 1){
                        return  <li onClick={rePlay} key={String(operate.id)} className="cursor-pointer hover_color">{operate.title}</li>
                    }else if(operate.id === 2){
                        return  <li onClick={retract} key={String(operate.id)} className="cursor-pointer hover_color">{operate.title}</li>
                    }else if(operate.id === 3){
                        return  <li onClick={removeRetract} key={String(operate.id)} className="cursor-pointer hover_color">{operate.title}</li>
                    }
                })}
            </ul>
        </div>
    </>
}
